package com.kyrie.lib_sys.utils.learn.TimeDemo;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class TimeDemo07 {

    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 校验时间点顺序 + 时间区间重叠（按员工分组）
     * @param timeList
     * @return boolean
     */
    public static boolean timeListCheck(List<Map<String, String>> timeList) {
        // 先按员工分组，再在每个员工内部进行时间顺序和区间重叠的校验
        // 员工时间段分组，key = pk_psndoc
        Map<String, List<TimeInterval>> employeeTimeMap = new HashMap<>();

        for (int i = 0; i < timeList.size(); i++) {
            Map<String, String> task = timeList.get(i);
            String pk_psndoc = task.getOrDefault("pk_psndoc", "unknown");

            List<LocalDateTime> timePoints = new ArrayList<>();

            if (task.containsKey("prepareTime")) timePoints.add(LocalDateTime.parse(task.get("prepareTime"), formatter));
            if (task.containsKey("travelTime")) timePoints.add(LocalDateTime.parse(task.get("travelTime"), formatter));
            if (task.containsKey("startTime")) timePoints.add(LocalDateTime.parse(task.get("startTime"), formatter));
            if (task.containsKey("completeTime")) timePoints.add(LocalDateTime.parse(task.get("completeTime"), formatter));

            // 顺序校验
            for (int j = 1; j < timePoints.size(); j++) {
                if (!timePoints.get(j - 1).isBefore(timePoints.get(j))) {
                    System.out.printf("员工 [%s] 的时间点 \"%s\" 存在时间顺序错误\n", pk_psndoc, timePoints.get(j).format(formatter));
                    return false;
                }
            }

            // 构造时间区间
            if (!timePoints.isEmpty()) {
                LocalDateTime start = Collections.min(timePoints);
                LocalDateTime end = Collections.max(timePoints);
                TimeInterval interval = new TimeInterval(start, end, i + 1); // 加入记录序号

                // 重叠校验：仅校验与同员工已有区间的重叠
                List<TimeInterval> existing = employeeTimeMap.getOrDefault(pk_psndoc, new ArrayList<>());
                for (TimeInterval exist : existing) {
                    if (interval.overlaps(exist)) {
                        System.out.printf("员工 [%s] 的记录%d[%s ~ %s] 与记录%d[%s ~ %s] 存在时间重叠错误\n",
                                pk_psndoc,
                                interval.index, formatter.format(interval.start), formatter.format(interval.end),
                                exist.index, formatter.format(exist.start), formatter.format(exist.end)
                        );
                        return false;
                    }
                }

                // 添加到对应员工的时间列表
                existing.add(interval);
                employeeTimeMap.put(pk_psndoc, existing);
            }
        }

        return true;
    }

    /**
     * 时间区间结构体（含序号）
     */
    static class TimeInterval {
        LocalDateTime start;
        LocalDateTime end;
        int index; // 原始记录序号（便于报错提示）

        TimeInterval(LocalDateTime start, LocalDateTime end, int index) {
            this.start = start;
            this.end = end;
            this.index = index;
        }

        boolean overlaps(TimeInterval other) {
            return !(this.end.isBefore(other.start) || this.start.isAfter(other.end));
        }
    }

    public static void main(String[] args) {
        List<Map<String, String>> timeList = new ArrayList<>();

        Map<String, String> time1 = new HashMap<>();
        time1.put("pk_psndoc", "E01");
        time1.put("prepareTime", "2025-07-01 09:00:00");
        time1.put("travelTime", "2025-07-01 09:10:00");
        time1.put("completeTime", "2025-07-01 09:30:00");

        Map<String, String> time2 = new HashMap<>();
        time2.put("pk_psndoc", "E01");
        time2.put("prepareTime", "2025-07-01 09:20:00"); // 与 time1 有重叠

        Map<String, String> time3 = new HashMap<>();
        time3.put("pk_psndoc", "E02");
        time3.put("prepareTime", "2025-07-01 10:00:00");
        time3.put("startTime", "2025-07-01 10:30:00");

        timeList.add(time1);
        timeList.add(time2);
        timeList.add(time3);

        boolean result = timeListCheck(timeList);
        System.out.println("校验结果: " + result);
    }
}
